﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

[CreateAssetMenu(fileName = "AnimationEventSet", menuName = "BoyInABox/AnimationEventSet")]
public class AnimationEvent_Object : ScriptableObject
{
    #region Variables

    private Dictionary<string, Animation_EventInfo> m_animEventInfoDic = new Dictionary<string, Animation_EventInfo>();

    public List<Animation_EventInfo> events;

    #endregion Variables

    #region Custom Methods

    public void SetAnimationEvent()
    {
        m_animEventInfoDic.Clear();

        foreach (var e in events)
        {
            if (string.IsNullOrEmpty(e.animationName))
                return;

            if (!m_animEventInfoDic.ContainsKey(e.animationName))
            {
                e.SetAnimationEvent();
                m_animEventInfoDic.Add(e.animationName, e);
            }
        }
    }

    public UnityEvent<AnimationEvent_Value> GetAnimationEvent(string animName, string eventName)
    {
        if (m_animEventInfoDic.ContainsKey(animName))
            return m_animEventInfoDic[animName].GetAnimationEvent(eventName);
        else
            return null;
    }

    #endregion Custom Methods
}

#region Properties

[System.Serializable]
public struct AnimationEvent_Value
{
    public string stringValue;
    public float floatValue;
    public bool boolValue;
}

[System.Serializable]
public class Animation_EventInfo
{
    private Dictionary<string, UnityEvent<AnimationEvent_Value>> m_animEventDic = new Dictionary<string, UnityEvent<AnimationEvent_Value>>();

    public string animationName;

    public List<Animation_Event> animEvents = new List<Animation_Event>();

    [System.Serializable]
    public class Animation_Event
    {
        public string eventName;

        [Range(0f, 1f)]
        public float invokeNormalizedTime;

        public AnimationEvent_Value eventValue;

        protected bool m_isInvoked;

        public void InvokeEvent(Animation_EventInfo eventInfo)
        {
            if (m_isInvoked) return;

            eventInfo.GetAnimationEvent(eventName).Invoke(eventValue);

            m_isInvoked = true;
        }

        public void ResetEvent()
        {
            if (!m_isInvoked) return;
            m_isInvoked = false;
        }
    }

    public void SetAnimationEvent()
    {
        m_animEventDic.Clear();

        foreach (var e in animEvents)
        {
            m_animEventDic.Add(e.eventName, new UnityEvent<AnimationEvent_Value>());
        }
    }

    public UnityEvent<AnimationEvent_Value> GetAnimationEvent(string name)
    {
        if (m_animEventDic.ContainsKey(name))
            return m_animEventDic[name];
        else
            return null;
    }
}

#endregion Properties